package com.yykj.drup.server.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yykj.common.service.RedisService;
import com.yykj.common.util.RandomUtil;
import com.yykj.drup.server.constant.SysConstant;
import com.yykj.drup.server.dto.PrescriptionProductDto;
import com.yykj.drup.server.dto.PrescriptionStoreProductDto;
import com.yykj.drup.server.form.OrderForm;
import com.yykj.drup.server.mapper.OrderDao;
import com.yykj.drup.server.model.Order;
import com.yykj.drup.server.model.OrderInfo;
import com.yykj.drup.server.model.Product;
import com.yykj.drup.server.param.OrderProductParam;
import com.yykj.drup.server.service.OrderService;
import com.yykj.drup.server.service.ProductService;
import com.yykj.drup.server.service.feign.PrescriptionServerFeign;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zengg
 * @since 2022-03-30
 */
@Service
@AllArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements OrderService {

    final RedisService redisService;
    final OrderDao orderDao;
    final ProductService productService;
    final PrescriptionServerFeign prescriptionServerFeign;
    @Override
    public String insertSysOrder(OrderForm orderForm) {
        Order order = new Order();
        //生成系统订单编号
        String numbers = RandomUtil.randomNumbers(12);
        order.setOrderSysNumber(numbers);
        order.setOrderDoctorName(orderForm.getPrescriptionDoctor());
        order.setPayType(orderForm.getPayType());
        order.setConsultUserId(orderForm.getConsultUserId());
        order.setConsultUserName(orderForm.getConsultUserName());
        order.setConsultUserAddress(orderForm.getConsultUserAddress());
        order.setConsultUserPhone(orderForm.getConsultUserPhone());
        order.setHospitalId(orderForm.getHospitalId());
        order.setPrescriptionId(orderForm.getPrescriptionId());
        BigDecimal totalPrice = this.getOrderTotalPrice(orderForm.getStoreProductDtos());
        order.setOrderTotalPrice(totalPrice);
        boolean save = this.save(order);
        if (save){
            return order.getOrderSysNumber();
        }
        return null;
    }

    @Override
    public BigDecimal getOrderTotalPrice(List<PrescriptionStoreProductDto> storeProductDtos) {
        BigDecimal totalPrice = new BigDecimal(0);
        for (PrescriptionStoreProductDto storeProductDto : storeProductDtos) {
            BigDecimal orderPrice = this.getStoreOrderPrice(storeProductDto);
            totalPrice = totalPrice.add(orderPrice);
        };
        return totalPrice;
    }

    @Override
    public BigDecimal getStoreOrderPrice(PrescriptionStoreProductDto prescriptionStoreProductDto) {
        BigDecimal totalPrice = new BigDecimal(0);
        List<PrescriptionProductDto> products = prescriptionStoreProductDto.getProducts();
        if (!products.isEmpty()){
            for (PrescriptionProductDto product : products) {
                Product p = productService.getById(product.getId());
                BigDecimal price = p.getPrice().multiply(new BigDecimal(product.getProductNumber()));
                totalPrice = totalPrice.add(price);
            };
        }
        return totalPrice;
    }

    @Override
    public Integer getStoreProductCount(PrescriptionStoreProductDto prescriptionStoreProductDto) {
        Integer count = 0;
        List<PrescriptionProductDto> products = prescriptionStoreProductDto.getProducts();
        if (!products.isEmpty()){
            for (PrescriptionProductDto product : products) {
                count += product.getProductNumber();
            };
        }
        return count;
    }

    @Override
    public void cancelOrderStatus(String sysOrderNum) {

        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getOrderStatus,4)
                .eq(Order::getOrderStatus,1)
                .eq(Order::getOrderSysNumber,sysOrderNum);
        this.update(wrapper);
    }

    @Override
    public Long getCancelTime() {
        String timeout = redisService.get("orderPayTimeout");
        LocalDateTime localDateTime = LocalDateTime.now();
        if (StrUtil.isEmpty(timeout)){
            timeout = SysConstant.timeoutDef;
        }
        LocalDateTime minusMinutes = localDateTime.plusMinutes(Integer.parseInt(timeout));
        System.out.println(minusMinutes);
        return minusMinutes.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }


    @Override
    public IPage<Order> findOrderInfosPage(OrderProductParam param) {
        IPage<Order> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        List<Order> infoList = orderDao.findOrdersPage(page, param.getOrderNum(), param.getOrderStatus(),param.getConsultUserId());
        return page.setRecords(infoList);
    }

    @Override
    public Order findOrderDeteilsById(Integer orderSysId) {
        return orderDao.findOrderDeteilsById(orderSysId);
    }

    @Override
    public Order getByOrderNum(String orderNum) {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("order_sys_number",orderNum);
        return this.getOne(wrapper);
    }

    @Override
    public Integer updateOrderStatus(String orderNum) {
        Order order = this.getByOrderNum(orderNum);
        if (order == null){
            throw new RuntimeException("订单不存在");
        }
        order.setOrderStatus(2);
        order.setPayTime(LocalDateTime.now());
        return orderDao.updateById(order);
    }

    @Override
    public IPage<OrderInfo> getOrderInfosPage(IPage page, LambdaQueryWrapper<Order> wrapper) {
        IPage iPage = orderDao.selectPage(page, wrapper);
        return iPage;
    }
}
